home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / commands / ast.c < prev    next >
C/C++ Source or Header  |  1990-07-15  |  6KB  |  281 lines

  1. /* ast - add symbol table.        Author: Dick van Veen */
  2.  
  3. #include <sys/types.h>
  4. #include <fcntl.h>
  5. #include <a.out.h>
  6. #include <stdio.h>
  7.  
  8. /* Since the a.out file in MINIX does not contain any symbol table,
  9.  * we use the symbol table produced with the -s option of asld.
  10.  *
  11.  * Read symbol table in memory, remove compiler generated labels,
  12.  * sort the labels and add it to the a.out file.
  13.  *
  14.  * When finally there comes a real as and ld, we may also get
  15.  * a symbol table in the a.out file, and we can forget this program.
  16.  *
  17.  */
  18.  
  19. /* Ast [flags] [file] [symbolfile]
  20.  *
  21.  * flags:
  22.  *    -x    do not preserve local symbols
  23.  *    -X    preserve local symbols except for those whose name begin
  24.  *        with 'I', these are compiler generated.
  25.  *
  26.  *    -    when no symbol file is present, symbol.out is assumed.
  27.  *    -    when no file is present, a.out is assumed.
  28.  *    -    when one file name is present it must be the executable file
  29.  *    -    just one flag may be pressent.
  30.  *
  31.  */
  32.  
  33. #define A_OUT        "a.out"
  34. #define SYMBOL_FILE    "symbol.out"    /* contains symbol table */
  35. #define LINE_LENGTH    24
  36.  
  37. #define WORTH_LESS    1    /* lines contain no symbol */
  38. #define LAST_LINE    2    /* end of file reached */
  39.  
  40. struct exec header;        /* header info of a.out file */
  41.  
  42. int x_flag;            /* flags to ast */
  43. int X_flag;
  44. int o_flag;
  45.  
  46. char *s_file, *o_file;        /* names of files used by ast */
  47. FILE *s_fd, *o_fd;        /* file descriptors of those files */
  48. int nr_symbols;            /* number of symbols added */
  49. char buffer[LINE_LENGTH];    /* contains line of symbol file */
  50.  
  51. char io_buf[BUFSIZ];        /* for buffered output on stderr */
  52. unsigned int get_value();    /* forward definition */
  53.  
  54. main(argc, argv)
  55. int argc;
  56. char **argv;
  57. {
  58.   extern FILE *fopen();
  59.  
  60.   argv++;
  61.   if (*argv != NULL && **argv == '-') {
  62.     *argv += 1;
  63.     if (**argv == 'x')
  64.         x_flag = 1;
  65.     else if (**argv == 'X')
  66.         X_flag = 1;
  67.     else {
  68.         fprintf(stderr, "illegal flag: -%c\n", **argv);
  69.         exit(-1);
  70.     }
  71.     argv++;
  72.   }
  73.   if (*argv != NULL) {
  74.     o_file = *argv;
  75.     argv++;
  76.   }
  77.   if (*argv != NULL) {
  78.     s_file = *argv;
  79.     argv++;
  80.   }
  81.   if (*argv != NULL) {
  82.     fprintf(stderr, "Usage: ast [-{x,X}] [file] [symbolfile]\n");
  83.     exit(-1);
  84.   }
  85.   if (o_file == NULL) o_file = A_OUT;
  86.   o_fd = fopen(o_file, "a");
  87.   if (o_fd == NULL) {
  88.     fprintf(stderr, "can't open %s\n", o_file);
  89.     exit(-1);
  90.   }
  91.   if (s_file == NULL) s_file = SYMBOL_FILE;
  92.   s_fd = fopen(s_file, "r");
  93.   if (s_fd == NULL) {
  94.     fprintf(stderr, "can't open %s\n", s_file);
  95.     exit(-1);
  96.   }
  97.   setbuf(s_fd, io_buf);
  98.   ast(s_fd, o_fd);
  99.   exit(0);
  100. }
  101.  
  102. ast(s_fd, o_fd)
  103. FILE *s_fd, *o_fd;
  104. {
  105.   struct nlist symbol;
  106.   int line_type;
  107.  
  108.   do_header();
  109.   for (;;) {
  110.     read_line(s_fd, buffer);
  111.     line_type = transform_line(buffer, &symbol);
  112.     if (line_type == WORTH_LESS) continue;
  113.     if (line_type == LAST_LINE) break;
  114.     save_line(o_fd, &symbol);
  115.   }
  116.   redo_header(o_fd);
  117. }
  118.  
  119. read_line(fd, buffer)
  120. FILE *fd;
  121. char *buffer;
  122. {
  123.   int ch;
  124.   char *buf1;
  125.  
  126.   buf1 = buffer;
  127.   *buffer = '\n';
  128.   ch = fgetc(fd);
  129.   while (ch != '\n' && ch != EOF) {
  130.     *buffer = ch;
  131.     buffer++;
  132.     ch = fgetc(fd);
  133.   }
  134.   if (ch == EOF)
  135.     *buffer = '\0';
  136.   else
  137.     *buffer = '\n';
  138.   buffer[1] = '\0';
  139. }
  140.  
  141. transform_line(buffer, symbol)
  142. char *buffer;
  143. struct nlist *symbol;
  144. {
  145.   switch (*buffer) {
  146.       case 'a':            /* absolute symbol */
  147.     symbol->n_sclass = N_ABS;
  148.     break;
  149.       case 'A':    symbol->n_sclass = N_ABS | C_EXT;    break;
  150.       case 'u':            /* undefined symbol */
  151.     symbol->n_sclass = N_UNDF;
  152.     break;
  153.       case 'U':
  154.     symbol->n_sclass = N_UNDF | C_EXT;
  155.     break;
  156.  
  157.       case 't':            /* text symbol */
  158.     symbol->n_sclass = N_TEXT;
  159.     break;
  160.       case 'T':
  161.     symbol->n_sclass = N_TEXT | C_EXT;
  162.     break;
  163.       case 'd':
  164.     symbol->n_sclass = N_DATA;
  165.       case 'D':            /* data symbol */
  166.     symbol->n_sclass = N_DATA | C_EXT;
  167.     break;
  168.       case 'b':
  169.     symbol->n_sclass = N_BSS;
  170.       case 'B':            /* bss symbol */
  171.     symbol->n_sclass = N_BSS | C_EXT;
  172.     break;
  173.       case '\0':        /* reached end of file */
  174.     return(LAST_LINE);
  175.       default:            /* one of first two lines */
  176.     return(WORTH_LESS);
  177.   }
  178.  
  179.   if (buffer[1] != ' ') {
  180.     fprintf(stderr, "illegal file format\n");
  181.     exit(-1);
  182.   }
  183.   symbol->n_value = get_value(buffer + 2);
  184.  
  185.   if (buffer[6] != ' ') {
  186.     fprintf(stderr, "illegal file format\n");
  187.     exit(-1);
  188.   }
  189.   get_name(buffer + 7, symbol->n_name);
  190.   return(0);            /* yeah, found a symbol */
  191. }
  192.  
  193. save_line(fd, symbol)
  194. FILE *fd;
  195. struct nlist *symbol;
  196. {
  197.   if (!(symbol->n_sclass & C_EXT)) {    /* local symbol */
  198.     if (x_flag) return;
  199.     if (X_flag && symbol->n_name[0] == 'I') return;
  200.     if (X_flag && symbol->n_name[0] == 'L') return;
  201.   }
  202.   if (fwrite(symbol, sizeof(struct nlist), 1, fd) != 1) {
  203.     fprintf(stderr, "can't write %s\n", o_file);
  204.     exit(-1);
  205.   }
  206.   nr_symbols++;
  207. }
  208.  
  209. unsigned get_value(string)
  210. char *string;
  211. {
  212.   unsigned value;
  213.   int shift, bits;
  214.  
  215.   value = 0;
  216.   for (shift = 0; shift < 16; shift += 4) {
  217.     bits = get_bits(*string);
  218.     value = (value << 4) | bits;
  219.     string++;
  220.   }
  221.   return(value);
  222. }
  223.  
  224. get_bits(ch)
  225. char ch;
  226. {
  227.   if (ch >= '0' && ch <= '9') return(ch - '0');
  228.   if (ch >= 'A' && ch <= 'F') return (ch - 'A' + 10);
  229.   if (ch >= 'a' && ch <= 'f') return (ch - 'a' + 10);
  230.   fprintf(stderr, "illegal file format\n");
  231.   exit(-1);
  232. }
  233.  
  234. get_name(str1, str2)
  235. register char *str1, *str2;
  236. {
  237.   int count;
  238.  
  239.   for (count = 0; count < 8; count++) {
  240.     if (*str1 == '\n') break;
  241.     *str2++ = *str1++;
  242.   }
  243.   while (count < 8) {
  244.     *str2++ = '\0';
  245.     count++;
  246.   }
  247. }
  248.  
  249. do_header()
  250. {
  251.   int fd;
  252.  
  253.   fd = open(o_file, O_RDONLY);
  254.   if (read(fd, &header, sizeof(struct exec)) != sizeof(struct exec)) {
  255.     fprintf(stderr, "%s: no executable file\n", o_file);
  256.     exit(-1);
  257.   }
  258.   if (BADMAG(header)) {
  259.     fprintf(stderr, "%s: bad header\n", o_file);
  260.     exit(-1);
  261.   }
  262.   if (header.a_syms != 0L) {
  263.     fprintf(stderr, "%s: symbol table is installed\n", o_file);
  264.     exit(-1);
  265.   }
  266.   fseek(o_fd, A_SYMPOS(header), 0);
  267.   nr_symbols = 0;
  268.   close(fd);
  269. }
  270.  
  271. redo_header(fd)
  272. FILE *fd;
  273. {
  274.   header.a_syms = (long) (nr_symbols * sizeof(struct nlist));
  275.   fseek(fd, 0L, 0);
  276.   if (fwrite(&header, sizeof(header), 1, fd) != 1) {
  277.     fprintf(stderr, "%s: can't write\n", o_file);
  278.     exit(-1);
  279.   }
  280. }
  281.